package com.mingte.manghe.interceptory;

import com.mingte.manghe.annotation.LoginRequired;
import com.mingte.manghe.common.ResponseResult;
import com.mingte.manghe.dto.TeaUserDTO;
import com.mingte.manghe.utils.JwtUtils;
import com.mingte.manghe.utils.RedisUtils;
import com.mingte.manghe.utils.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author ：luxinsheng
 * @Email ：282860642@qq.com
 * @date ：Created in 2021/11/25 14:17
 * @description：登录校验拦截器
 * @modified By：
 * @version: $
 */

//@Aspect
//@Component
public class JwtInterceptor {

    private final Logger logger = LoggerFactory.getLogger(JwtInterceptor.class);

    private static int reqCount = 0;

    private static Map<String, Integer> threadCount = new HashMap<>();

    private final static ReentrantLock reentrantLock = new ReentrantLock();


    @Autowired
    private RedisUtils redisUtils;

    /**
     * 定义拦截规则：拦截com.mingte.manghe.controller包下面的所有类中，有@RequestMapping注解的方法。
     */
    /*@Pointcut("execution(* com.mingte.manghe.controller..*.*(..))" +
            " && ( @annotation(org.springframework.web.bind.annotation.RequestMapping )" +
            " || @annotation(org.springframework.web.bind.annotation.GetMapping) " +
            " || @annotation(org.springframework.web.bind.annotation.PostMapping ))")*/

    @Pointcut("execution(* com.mingte.manghe.controller..*.*(..))" +
            " && execution(* com.mingte.manghe.config.WebConfig..*.*(..))")
    public void point(){};

    @Before("point()")
    public void before(JoinPoint joinPoint){
    }


    @Around("point()")
    public Object around(ProceedingJoinPoint joinPoint){
        //reentrantLock.lock();
        ++reqCount;
        logger.info("当前请求总数{}===当前线程=====>{}",reqCount,Thread.currentThread().getName());
        /*Integer integer = threadCount.get(name);
        if(null == integer){
            threadCount.put(name,1);
        }else{
            threadCount.put(name,++integer);
        }

        if(reqCount >= 20000){
            Set<Map.Entry<String, Integer>> entries = threadCount.entrySet();
            for (Map.Entry<String, Integer> map:entries) {
                System.out.println(map.getKey()+"======="+map.getValue());
            }
        }*/

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        /*String requestURI = request.getRequestURI();
        Cookie[] cookies = request.getCookies();
        String requestMethodName = request.getMethod();
        StringBuffer requestURL = request.getRequestURL();
        String requestedSessionId = request.getRequestedSessionId();
        String contextPath = request.getContextPath();
        String authType = request.getAuthType();
        String pathInfo = request.getPathInfo();
        String remoteHost = request.getRemoteHost();
        Object target = joinPoint.getTarget().getClass();*/

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Object object = null;
        
        try {
        
            LoginRequired annotation = method.getAnnotation(LoginRequired.class);
            if(null == annotation){
                object = joinPoint.proceed();
            }else{
                String access_mh_token = request.getHeader("access_mh_token");
                if(annotation.needLogin()
                        && StringUtils.isNotEmpty(access_mh_token)
                        && checkJwtToken(access_mh_token)){
                    object = joinPoint.proceed();
                }
            }

            return null == object ? ResponseResult.noLogin() : object;
        } catch (Throwable throwable) {
            logger.error("登录拦截器错误提示========》{}",throwable.getMessage());
            //throwable.printStackTrace();
            return ResponseResult.fail(throwable.getMessage());
        } finally {
            //reentrantLock.unlock();
        }
    }


    @After("point()")
    public void after(JoinPoint joinPoint){
    }

    /**
     * 验证token是否合格
     * @param token
     * @return
     */
    public boolean checkJwtToken(String token) throws RuntimeException{
        //这里添加验证过程
        // 验证 token
        if(JwtUtils.checkSign(token)){
            String userId = JwtUtils.getUserId(token);
            if(StringUtils.isNotEmpty(userId)){
                TeaUserDTO teaUserDTO = (TeaUserDTO)redisUtils.get(userId);
                if(null != teaUserDTO){
                    return teaUserDTO.getAccessMhToken().equals(token);
                }
            }
        }
        return false;
    }

}
